package cn.android.common.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * View工具类
 * 
 * @author RenHui
 */
public class ViewUtils {

	private static final String CLASS_NAME_GRID_VIEW = "android.widget.GridView";
	private static final String FIELD_NAME_VERTICAL_SPACING = "mVerticalSpacing";

	/**
	 * 私有构造函数
	 */
	private ViewUtils() {
		throw new AssertionError();
	}

	/**
	 * 获取GridView的垂直间距(获取的是系统函数定义的间距)
	 * 
	 * @param view
	 * @return
	 */
	public static int getGridViewVerticalSpacing(GridView view) {
		Class<?> demo = null;
		int verticalSpaceing = 0;
		try {
			demo = Class.forName(CLASS_NAME_GRID_VIEW);
			Field field = demo.getDeclaredField(FIELD_NAME_VERTICAL_SPACING);
			field.setAccessible(true);
			verticalSpaceing = (Integer) field.get(view);
		} catch (Exception e) {
			/**
			 * accept all exception, include ClassNotFoundException,
			 * NoSuchFieldException, InstantiationException,
			 * IllegalArgumentException, IllegalAccessException,
			 * NullPointException
			 */
			e.printStackTrace();
		}
		return verticalSpaceing;
	}

	/**
	 * 获取到AbsListView的高度，通过测量每个children View的高度 
	 * 注： 因为measure 方法只能在onMeasure的重写的 方法里面使用
	 * 
	 * @param view
	 * @return
	 */
	public static int getAbsListViewHeightBasedOnChildren(AbsListView view) {
		ListAdapter adapter;
		if (view == null || (adapter = view.getAdapter()) == null) {
			return 0;
		}

		int height = 0;
		for (int i = 0; i < adapter.getCount(); i++) {
			View item = adapter.getView(i, null, view);
			if (item instanceof ViewGroup) {
				item.setLayoutParams(new LayoutParams(
						LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
			}

			item.measure(0, 0);
			height += item.getMeasuredHeight();
		}
		height += view.getPaddingTop() + view.getPaddingBottom();
		return height;
	}

	/**
	 * 获取到ListView的高度，通过测量每个children View的高度
	 * 
	 * @param view
	 * @return
	 */
	public static int getListViewHeightBasedOnChildren(ListView view) {
		int height = getAbsListViewHeightBasedOnChildren(view);
		ListAdapter adapter;
		int adapterCount;
		if (view != null && (adapter = view.getAdapter()) != null
				&& (adapterCount = adapter.getCount()) > 0) {
			height += view.getDividerHeight() * (adapterCount - 1);
		}
		return height;
	}

	/**
	 * 设定view的高度为指定的高度
	 * 
	 * @param view
	 * @param height
	 */
	public static void setViewHeight(View view, int height) {
		if (view == null) {
			return;
		}

		ViewGroup.LayoutParams params = view.getLayoutParams();
		params.height = height;
	}

	/**
	 * 设置 AbsListView的高度（高度的大小由@link
	 * {@link #getListViewHeightBasedOnChildren(ListView)}来测量的）
	 * 
	 * @param view
	 */
	public static void setListViewHeightBasedOnChildren(ListView view) {
		setViewHeight(view, getListViewHeightBasedOnChildren(view));
	}

	/**
	 * 设置 AbsListView的高度（高度的大小由@link
	 * #getAbsListViewHeightBasedOnChildren(AbsListView)来测量的）
	 * 
	 * @param view
	 */
	public static void setAbsListViewHeightBasedOnChildren(AbsListView view) {
		setViewHeight(view, getAbsListViewHeightBasedOnChildren(view));
	}

	/**
	 * 为SearchView设置点击事件 TODO ：貌似是因为直接对
	 * SearchView进行setOnClickListener不起作用，目前没进行测试过
	 * 
	 * @param searchView
	 * @param listener
	 */
	public static void setSearchViewOnClickListener(View searchView,
			OnClickListener listener) {
		if (searchView instanceof ViewGroup) {
			ViewGroup group = (ViewGroup) searchView;
			int count = group.getChildCount();
			for (int i = 0; i < count; i++) {
				View child = group.getChildAt(i);
				if (child instanceof LinearLayout
						|| child instanceof RelativeLayout) {
					setSearchViewOnClickListener(child, listener);
				}

				if (child instanceof TextView) {
					TextView text = (TextView) child;
					text.setFocusable(false);
				}
				child.setOnClickListener(listener);
			}
		}
	}

	/**
	 * 提取指定的View对象（从有子View的对象中）
	 * 
	 * @param parent
	 * @param filter
	 *            需要返回的View的对象
	 * @param includeSubClass
	 *            是否规则的子类也能够起作用
	 * @return
	 */
	public static <T extends View> List<T> getDescedants(ViewGroup parent,
			Class<T> filter, boolean includeSubClass) {
		List<T> descendedViewList = new ArrayList<T>();
		int childCount = parent.getChildCount();
		for (int i = 0; i < childCount; i++) {
			View child = parent.getChildAt(i);
			Class<? extends View> childsClass = child.getClass();
			if ((includeSubClass && filter.isAssignableFrom(childsClass))
					|| (!includeSubClass && childsClass == filter)) {
				descendedViewList.add(filter.cast(child));
			}

			if (child instanceof ViewGroup) {
				descendedViewList.addAll(getDescedants((ViewGroup) child,
						filter, includeSubClass));
			}
		}
		return descendedViewList;
	}

}
